package com.gitee.wsl.io.file

import kotlinx.io.Sink
import kotlinx.io.files.Path
import kotlin.math.min

class RandomAccessFileImpl(val raf: java.io.RandomAccessFile) : RandomAccessFile {

    constructor(path: Path):this(java.io.RandomAccessFile(path.toString(), "rw"))

    override fun readBytes(position: Long, bytes: ByteArray, offset: Int, length: Int) {
        raf.seek(position)
        raf.read(bytes, offset, length)
    }

    override fun writeBytes(position: Long, bytes: ByteArray, offset: Int, length: Int) {
        raf.seek(position)
        raf.write(bytes, offset, length)
    }

//    override fun writeMemory(position: Long, memory: Memory) {
//        raf.seek(position)
//        val buffer = Buffer()
//        memory.rawSource().use { source ->
//            do {
//                val written = source.readAtMostTo(buffer, SPLITTER)
//                if (written > 0) {
//                    raf.write(buffer.readByteArray())
//                }
//            } while (written > 0)
//        }
//    }

    override fun transferTo(position: Long, sink: Sink, length: Long) {
        raf.seek(position)
        val data = ByteArray(SPLITTER.toInt())
        var stillToRead = length
        var read: Int
        var todo: Boolean
        var min: Int
        do {
            read = raf.read(data)
            todo = read > 0 && stillToRead > 0
            if (todo) {
                min = min(read.toLong(), stillToRead).toInt()
                sink.write(data, 0, min)
                stillToRead -= read
            }
        } while (todo)
    }

    override fun close() {
        raf.close()
    }

    companion object{
        const val SPLITTER = 4096L
    }

}